﻿using System;
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations;
using System.ComponentModel.DataAnnotations.Schema;
using System.Data;
using System.Linq;
using System.Reflection;
using System.Web;

namespace ProjectStatic.Models
{
    [Table("tables")]
    public class BaseModel
    {
        //public static string TableName = "tables";
        public BaseModel()
        { }


        /// <summary>
        /// 返回该类所对应的数据库表名
        /// </summary>
        /// <returns>表名</returns>
        public string GetTableName()
        {
            return this.GetType().
                       GetCustomAttributes(typeof(TableAttribute), true).Cast<TableAttribute>().SingleOrDefault().Name;
        }
        #region 从DataRow中读取每个property的数据
        protected virtual string ColumnName(string propName)
        {
            var propertyAttr = this.GetType().GetProperty(propName,BindingFlags.Public | BindingFlags.Instance).
                GetCustomAttributes(typeof(ColumnAttribute), true).
                Cast<ColumnAttribute>().SingleOrDefault().Name;
            return propertyAttr;
        }
        protected virtual string ColumnName(PropertyInfo propInfo)
        {
            var propertyAttr = propInfo.
                GetCustomAttributes(typeof(ColumnAttribute), true).
                Cast<ColumnAttribute>().SingleOrDefault().Name;
            return propertyAttr;
        }

        public virtual void FillPropertyWithDataRow(DataRow row)
        {
            foreach (var property in this.GetType().GetProperties(BindingFlags.Public | BindingFlags.Instance))
            {
                string attr = ColumnName(property);
                property.SetValue(this, Convert.ChangeType(row[attr], property.PropertyType), null);
                //property.SetValue(this, row[attr], null);
            }
        }
        #endregion
        /// <summary>
        /// 从类本身的属性中生成insert所需要的sql语句
        /// </summary>
        /// <returns>insert sql 语句</returns>
        public string GenerateInsertSqlStr(string tableName="")
        {
            if (tableName == "")
                tableName = this.GetTableName();
            string sql=string.Format("insert into [{0}] (",tableName);
            var propList = this.GetType().GetProperties(BindingFlags.Public | BindingFlags.Instance).ToList();
            var columNameList = propList.Select(p => ColumnName(p)).ToList();
            foreach (string str in columNameList)
            {
                sql = sql + str + ",";
            }
            sql = sql.Substring(0, sql.Length-1);
            sql = sql + ") VALUES (";
            foreach (var p in propList)
            {
                string temp = "";
                try
                {
                    temp = p.GetValue(this, null).ToString();
                }
                catch
                {
                    temp = "";
 
                }
                if (p.PropertyType == typeof(double) || p.PropertyType == typeof(int))
                {
                   
                }
                else
                {
                    temp = string.Format("'{0}'", temp);
                }
                sql += temp + ",";
            }
            sql = sql.Substring(0, sql.Length-1);
            sql = sql + ")";
            return sql;
        }

        /// <summary>
        /// 从类本身的属性中生成delete所需要的sql语句
        /// </summary>
        /// <returns>insert sql 语句</returns>
        public string GenerateDeleteSqlStr(string tableName = "")
        {
            if (tableName == "")
                tableName = this.GetTableName();
            return string.Format("delete from {0}{1}", tableName, GenerateQueryString());
        }
        /// <summary>
        /// 从类本身的属性中生成query where所需要的sql语句
        /// </summary>
        /// <returns>insert sql 语句</returns>
        public string GenerateFindSqlStr(string tableName = "")
        {
            if (tableName == "")
                tableName = this.GetTableName();
            return string.Format("select * from {0}{1}", tableName, GenerateQueryString());
        }
        protected string GenerateQueryString()
        {
            var primaryPropList = this.GetType().GetProperties().
                Where(p => p.IsDefined(typeof(DisplayAttribute), false)).ToList();
            string queryStr = " where ";
            for (int i = 0; i < primaryPropList.Count; i++)
            {
                var p = primaryPropList[i];
                string columnName = p.GetCustomAttributes(typeof(DisplayAttribute), true).
                Cast<DisplayAttribute>().SingleOrDefault().Name;
                if (i > 0)
                {
                    queryStr += " and ";
                }
                
                string temp = p.GetValue(this, null).ToString();
                if (p.PropertyType == typeof(double) || p.PropertyType == typeof(int))
                {

                }
                else
                {
                    temp = string.Format("'{0}'", temp);
                }
                queryStr += string.Format("{0} = {1}", columnName, temp);
            }
            return queryStr;
        }

    }
}